package com.lianxi.es;

import cn.hutool.json.JSONObject;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * api:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.5/java-rest-high-document-update.html
 * @author 张高飞
 * @date 2018/12/17
 */
public abstract class CommonEsHighService {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 添加数据
     */
    public int insert(Map<String,Object> data, String index) {
        try {
            IndexRequest request = new IndexRequest(index).source(data);
            return client.index(request, RequestOptions.DEFAULT).status().getStatus();
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }
    @Async
    public IndexResponse add(String json, String index, String id) {
        try {
            IndexRequest request = new IndexRequest(index).id(id).source(json, XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
            return client.index(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 批量添加数据
     */
    public BulkResponse insertSome(List<Map<String,Object>> datas, String index) {
        try {
            List<DocWriteRequest<?>> reqs = new ArrayList(datas.size());
            datas.forEach(el->{
                IndexRequest req = new IndexRequest(index).source(el);
                reqs.add(req);
            });
            BulkRequest bulkReqs = new BulkRequest(index).add(reqs);
            return client.bulk(bulkReqs,RequestOptions.DEFAULT);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public void insertTooManyTimesAsync(Map<String,Object> data, String index) {
        try {
            BulkRequest bulkReq = new BulkRequest(index).add(new IndexRequest(index).source(data)).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
            ActionListener<BulkResponse> bulkResponseActionListener = new ActionListener<BulkResponse>() {
                @Override
                public void onResponse(BulkResponse bulkResponse) {}
                @Override
                public void onFailure(Exception e) {}
            };
            client.bulkAsync(bulkReq,RequestOptions.DEFAULT,bulkResponseActionListener);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public BulkResponse insertTooManyTimesSync(Map<String,Object> data, String index) {
        try {
            BulkRequest bulkReq = new BulkRequest(index).add(new IndexRequest(index).source(data)).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
            return client.bulk(bulkReq,RequestOptions.DEFAULT);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 删除数据根据ID
     */
    public int delById(String index, String id) {
        try {
            DeleteRequest request = new DeleteRequest(index,id);
            return client.delete(request, RequestOptions.DEFAULT).status().getStatus();
        }catch (Exception e){
            e.printStackTrace();;
        }
        return 0;
    }

    /**
     * 更新文档
     * @throws Exception
     */
    public int updateById(Map<String,Object> data, String id, String index) {
        try {
            UpdateRequest request = new UpdateRequest(index, id).doc(data);
            return client.update(request, RequestOptions.DEFAULT).status().getStatus();
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 根据index、type、id进行查询----index,type,id
     */
    public GetResponse getById(String id, String index) {
        try {
            GetRequest getRequest = new GetRequest(index, id);
            return client.get(getRequest, RequestOptions.DEFAULT);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * sql查看
     */
    public List<Map<Object,Object>> excSql(String sql){
        String body = "";
        JSONObject json = new JSONObject();
        json.put("query",sql);
        try {
            Request post = new Request("POST", "/_sql?format=json");
            post.setJsonEntity(json.toString());
            Response response = client.getLowLevelClient().performRequest(post);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            response.getEntity().writeTo(baos);
            body = baos.toString().trim();
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject jsonObject = new JSONObject(body);
        Object[] columns = ((List<Map<String, String>>) jsonObject.get("columns")).toArray();
        List<List<Object>> rows = (List<List<Object>>) jsonObject.get("rows");
        List<Map<Object,Object>> objects = new ArrayList<>();
        rows.forEach(v->{
            Map<Object, Object> kv = new HashMap<>();
            for(int i = 0; i < v.size(); i++){
                Map<String,Object> cl = (Map<String, Object>) columns[i];
                kv.put(cl.get("name"),String.valueOf(v.get(i)));
            }
            objects.add(kv);
        });
        return objects;
    }

    /**
     * 关闭链接
     */
    public void close() {
        try {
            if(client != null){
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}